#include "parameter_set.h"
#include "ui_parameter_set.h"

parameter_set::parameter_set(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::parameter_set)
{
    ui->setupUi(this);
    ui->without_seq->setChecked(true);
}

parameter_set::~parameter_set()
{
    delete ui;
}

bool parameter_set::ip_valid(QString x)
{
    if(x=="")return false;
    QStringList tmp=x.split('.');
    int res=0;
    for(QString y:tmp){
        for(int i=0;i<y.length();i++){
            if(y[i]>='0'&&y[i]<='9'){
                res=(res<<1)+(res<<3)+y[i].toLatin1()-'0';
            }else{
                return false;
            }
        }
        if(res>255)return false;
        res=0;
    }
    return true;
}

bool parameter_set::port_valid(QString x)
{
    int res=0;
    for(auto y:x){
        if(y>='0'&&y<='9'){
            res=(res<<1)+(res<<3)+y.toLatin1()-'0';
        }else{
            return false;
        }
    }
    return res>=1&&res<=65535;
}

bool parameter_set::thread_counts_valid(QString x)
{
    int res=0;
    for(auto y:x){
        if(y>='0'&&y<='9'){
            res=(res<<1)+(res<<3)+y.toLatin1()-'0';
        }else{
            return false;
        }
    }
    return res>=1&&res<=500;
}

void parameter_set::on_pushButton_clicked()
{
    QStringList ip_list;
    std::pair<int,int>conseq_ports;
    std::vector<int>ports;
    int thread_cnt;
    QStringList tmp=ui->ip_line->text().split(',');
    //ip part
    if(ui->several_ip->isChecked()){
        for(QString x:tmp){
            if(ip_valid(x)){
                ip_list.append(x);
            }else{
                ui->error_line->setText("连续IP地址存在错误！/缺少IP地址");
                return;
            }
        }
        ui->error_line->setText("有效的连续IP地址！");
    }else{
        QString x=tmp[0];
        if(ip_valid(x)){
            ui->error_line->setText("有效的IP地址！");
            ip_list.append(x);
        }else{
            ui->error_line->setText("无效的IP地址！");
            return;
        }
    }
    //consequence ports check
    QString b_ports,e_ports,dis_port;
    QStringList d_ports;
    b_ports=ui->port_begin->text();
    e_ports=ui->port_end->text();
    if((b_ports.length()==0&&e_ports.length()>0)||(e_ports.length()==0&&b_ports.length()>0)){
        ui->error_line->setText("有终点端口号或起点端口号但缺少起始或终点端口号");
        return;
    }else if(b_ports.length()==0&&e_ports.length()==0){
        //nothing to do
    }else{
        if(port_valid(b_ports)){
            conseq_ports.first=b_ports.toInt();
            ui->error_line->setText("有效的起始端口号！");
        }else{
            ui->error_line->setText("无效的起始端口号！");
            return;
        }
        if(port_valid(e_ports)){
            conseq_ports.second=e_ports.toInt();
            ui->error_line->setText("有效的终点端口号！");
        }else{
            ui->error_line->setText("无效的终点端口号！");
            return;
        }
        if(conseq_ports.first>conseq_ports.second){
            if(ui->without_seq->isChecked()){
                std::swap(conseq_ports.first,conseq_ports.second);
            }else{
                ui->error_line->setText("终点端口号必须大于起点端口号！(或者勾选端口无序选项)");
                return;
            }
        }
    }
    //discreet ports part
    std::unordered_map<int,bool>exi;
    dis_port=ui->port_discreet->text();
    if(dis_port.length()>0){
        d_ports=dis_port.split(',');
        for(auto x:d_ports){
            if(port_valid(x)){
                if(exi[x.toInt()])continue;
                ports.push_back(x.toInt());
                exi[x.toInt()]=true;
            }else{
                ui->error_line->setText("存在空的端口号/无效的端口号(1-65535)！");
                return;
            }
        }
    }
    //threads part:
    if(thread_counts_valid(ui->thread_cnt_line->text())){
        thread_cnt=ui->thread_cnt_line->text().toInt();
        ui->error_line->setText("线程数有效!");
    }else{
        ui->error_line->setText("无效的线程数！(过大/过小/存在不合法字符)");
        return;
    }
    std::sort(ports.begin(),ports.end());
    emit parameter_set::paramater_end_set(ip_list,conseq_ports,ports,thread_cnt);
}


void parameter_set::on_nmap_pbn_clicked()
{
    ui->error_line->setText("请等待nmap工具运行结束！");
    QThread::msleep(300);
    QStringList ip_list;
    QStringList tmp=ui->ip_line->text().split(',');
    if(ui->several_ip->isChecked()){
        for(QString x:tmp){
            if(ip_valid(x)){
                ip_list.append(x);
            }else{
                ui->error_line->setText("连续IP地址存在错误！/缺少IP地址");
                return;
            }
        }
        ui->error_line->setText("有效的连续IP地址！");
    }else{
        QString x=tmp[0];
        if(ip_valid(x)){
            ui->error_line->setText("有效的IP地址！");
            ip_list.append(x);
        }else{
            ui->error_line->setText("无效的IP地址！");
            return;
        }
    }
    ui->several_ip->setChecked(true);
    QProcess process;
    QStringList arrguments;
    std::unordered_map<QString,bool>mp;
    arrguments<<"-sn";
    for(auto x:tmp){
        mp[x]=true;
        x+="/24";
        arrguments<<x;
    }
    for(auto f:arrguments){
        qDebug()<<f<<'\n';
    }
    QStringList res;
    connect(&process,&QProcess::readyReadStandardOutput,[&](){
        res=QString(process.readAllStandardOutput()).split('\n');
        for(auto x:res){
            if(x.contains("Nmap scan report for")){
                QStringList tmp=x.split(' ');
                if(tmp.size()==5){
                    if(mp[tmp[4]])continue;
                    QString y=ui->ip_line->text();
                    y+=","+tmp[4];
                    ui->ip_line->setText(y);
                    mp[tmp[4]]=true;
                }
            }
        }
        ui->error_line->setText("nmap工具运行结束！");
    });
    connect(&process,&QProcess::readyReadStandardError,[&](){
        qDebug()<<process.readAllStandardError();
    });
    process.start("nmap",arrguments);
    process.startDetached();
    process.waitForFinished();
}

